﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using cs499.Database;

namespace cs499.Classes
{
    public partial class ImportClass : System.Web.UI.Page
    {
        
        protected void Page_Load(object sender, EventArgs e)
        {
            if (HttpContext.Current.Session["ImportClassLabeltext"] != null && IsPostBack)
            {
                ImportClassLabel.Text = (string)HttpContext.Current.Session["ImportClassLabeltext"];
                //OKButton.Enabled = false;
            }
            else if (IsPostBack)
            {
                ImportClassLabel.Text = "";
            }
            else
            {
                ImportClassLabel.Text = "";
            }
        }

        protected void Page_PreRender(object sender, EventArgs e)
        {
            LinkButton classesMenuButton = (LinkButton)Master.FindControl("LoginView").FindControl("ClassesMenuButton");
            classesMenuButton.CssClass = "selected";

            if (ImportClassLabel.Text != "") return;
            if (HttpContext.Current.Session["CurrentDepartmentId"] != null)
            {
                int CurrentDepartmentId = (int)HttpContext.Current.Session["CurrentDepartmentId"];
                cs499.Database.Department CurrentDepartment = Database.ListOfDepartment.GetDepartment(ID: CurrentDepartmentId);
                ImportClassLabel.Text = "Input file containing information for new class in The " + CurrentDepartment.Name + " department";
            }
            else
            {
                Response.Redirect("~/Classes/ListClasses.aspx");
            }
        }

        protected void CancelButton_Click(object sender, EventArgs e)
        {
            Response.Redirect("~/Classes/ListClasses.aspx");
        }

        protected void importclassFileUpload_DataBinding(object sender, EventArgs e)
        {
            HttpContext.Current.Session["ImportClassLabeltext"] = "Bad parse";
            Server.Transfer("~/Classes/ImportClass.aspx", true);
        }

        protected void OKButton_Click(object sender, EventArgs e)
        {
            if (!importclassFileUpload.HasFile)
            {
                String errmsg = "User must Specify File";
                if (ImportClassLabel.Text != errmsg)
                {
                    HttpContext.Current.Session["ImportClassLabeltext"] = errmsg;
                    Server.Transfer("~/Classes/ImportClass.aspx", true);
                }
                return;
            }

            System.IO.StreamReader streamReader = new System.IO.StreamReader(importclassFileUpload.FileContent); 
            Model1Container db = new Model1Container();

            string line = null;
            int lineNumber = 0;
            List<string> coursesThatAlreadyExist = new List<string>();
            List<string> coursesAdded = new List<string>();
            System.Text.StringBuilder importStatus = new System.Text.StringBuilder();

            while ((line = streamReader.ReadLine()) != null)
            {
                lineNumber++;
                
                //only parse non-comment lines
                if (!line.StartsWith("#") && line != "" && line.Replace(",", "") != "")
                {
                    string[] fields = line.Split(',');
                    Course course = new Course();
                    try
                    {
                        //first bust out all of the field values
                        course.Number = Convert.ToInt32(fields[0]);
                        course.CourseTitle = fields[1];
                        //string departmentCode = fields[2];
                        int maximumEnrollment;
                        if (Int32.TryParse(fields[2], out maximumEnrollment))
                            course.MaximumEnrollment = maximumEnrollment;
                        else
                        {
                            //error
                            if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                            importStatus.Append("&emsp;&bull;The format for MaximumEnrollment was not correct.<br />");
                        }
                        int numberOfSections;
                        if (Int32.TryParse(fields[3], out numberOfSections))
                            course.NumberOfSections = numberOfSections;
                        else
                        {
                            //error
                            if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                            importStatus.Append("&emsp;&bull;The format for NumberOfSections was not correct.<br />");
                        }
                        

                        //find the department that's referenced, and set the relationship
                        int currentDepartmentId = (int)HttpContext.Current.Session["CurrentDepartmentId"];
                        Department department = db.Set<Department>().FirstOrDefault(dep => (dep.Id == currentDepartmentId)); //ListOfDepartment.GetDepartment(Code: departmentCode);
                        
                        if (fields.Length == 5) //place requirements are optional
                        {
                            string[] placeRequirements = fields[4].Split(';');
                            foreach (string placename in placeRequirements)
                            {
                                if (placename.Length > 0)
                                {
                                    Place placeobj = db.Set<Place>().Where(placetofind => placetofind.Department.Id == department.Id).FirstOrDefault(placetofind => placetofind.PlaceName == placename);
                                    if (placeobj == null)
                                    {
                                        if (!importStatus.ToString().Contains("Line #" + lineNumber))
                                            importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                                        importStatus.Append("&emsp;&bull;The place(s) you're trying to associate this course with do not exist.<br />");

                                        //we can't try to continue processing after this error. have to move on
                                        continue;
                                    }
                                    else
                                    {
                                        course.PlaceRequirements.Add(placeobj);
                                        course.PlaceRequirementsstring = course.PlaceRequirements.PlaceListToString();
                                    }
                                }
                            }
                        }
                        
                        course.Department = department;
                        course.DepartmentId = department.Id;

                        Course queriedCourse = department.GetCourse(number: course.Number);
                        if (queriedCourse == null)
                        {
                            //add new course to set that will go to database
                            db.Set<Course>().Add(course);
                            coursesAdded.Add(department.Code + course.Number);
                        }
                        else
                        {
                            //keep track of what we're not adding
                            coursesThatAlreadyExist.Add(department.Code + course.Number);
                        }
                    }
                    catch (Exception /*ex*/)
                    {
                        importStatus.Append("Line #" + lineNumber + ": " + line + "<br />");
                    }
                }
            }

            if (importStatus.Length != 0) //means we have reported errors
            {
                //insert the explanatory message before the errors
                importStatus.Insert(0, "There was an error processing the following line(s) in " + importclassFileUpload.FileName + "<br />");
                //add an extra space after the errors
                importStatus.Append("<br />");
                //tell the user what to do
                importStatus.Append("Please investigate and retry the import. No records were committed to the application.");

                ImportClassLabel.Text = importStatus.ToString();
                return;
            }
            else
            {
                //after all lines are successfully processed, then commit the changes to the database
                db.SaveChanges();

                //tell the user how many objects we imported
                importStatus.Append("Number of courses imported: " + coursesAdded.Count + "<br />");

                if (coursesAdded.Count > 0)
                {
                    //tell the user which objects were imported
                    importStatus.Append("Courses added: <ul>");
                    foreach (string slot in coursesAdded)
                        importStatus.Append("<li>" + slot + "</li>");
                    importStatus.Append("</ul>");
                }

                //if we didn't import anything, tell the user
                if (coursesThatAlreadyExist.Count > 0)
                {
                    importStatus.Append("<br />There were items that were not imported because they already existed in the application.<br />");
                    importStatus.Append("Number of courses skipped: " + coursesThatAlreadyExist.Count + "<br />");
                    //importStatus.Append("Time slots skipped: " + string.Join(", ", timeSlotsThatAlreadyExist.ToArray()));

                    importStatus.Append("Courses skipped: <ul>");
                    foreach (string slot in coursesThatAlreadyExist)
                        importStatus.Append("<li>" + slot + "</li>");
                    importStatus.Append("</ul>");
                }

                ImportClassLabel.Text = importStatus.ToString();
            }
        }
    }
}